package com.lamb.script.core.executor.loader;


import com.lamb.script.core.executor.IScriptContentProvider;
import com.lamb.script.core.executor.ScriptEngineCallable;
import com.lamb.script.core.utils.ScriptUtil;
import jdk.internal.dynalink.beans.StaticClass;

import javax.script.ScriptException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;

/**
 * 资源加载器.
 *
 * @author lamb
 */
public class ScriptResourceLoader implements IScriptContentProvider {
    private static List<String> IGNORE_TYPE_NAMES = Arrays.asList("Date", "String", "Boolean");

    private final ScriptEngineCallable scriptEngineCallable;

    public ScriptResourceLoader(ScriptEngineCallable scriptEngineCallable) {
        this.scriptEngineCallable = scriptEngineCallable;
    }

    /**
     * 导入其它jar.
     *
     * @param mavenJarFilePath mavenJar地址>.
     * @throws IOException 异常.
     */
    public void importJar(String mavenJarFilePath) throws Exception {
        scriptEngineCallable.getClassLoader().addJar(mavenJarFilePath);
    }

    /**
     * 加载类.
     *
     * @param className class.
     * @return 类对象.
     * @throws Exception 异常.
     */
    public StaticClass importClass(String className) throws Exception {
        // 加载类.
        Class<?> targetClass = scriptEngineCallable.getClassLoader().loadClass(className);
        StaticClass staticClass = StaticClass.forClass(targetClass);
        String typeName = targetClass.getSimpleName();
        if (IGNORE_TYPE_NAMES.contains(typeName)) {
            typeName = "Java" + typeName;
        }
        scriptEngineCallable.setAttribute(typeName, staticClass);
        return staticClass;
    }

    /**
     * 导入脚本.
     *
     * @param scriptNames 脚本.
     * @return 脚本加载对象.
     */
    public Object[] importScripts(String... scriptNames) throws ScriptException, IOException {
        if (scriptNames.length == 0) {
            return null;
        }
        Object[] result = new Object[scriptNames.length];
        for (int i = 0; i < scriptNames.length; i++) {
            String scriptName = scriptNames[i];
            byte[] bytes = ScriptUtil.readToByteBuffer(scriptName);
            result[i] = scriptEngineCallable.eval(ScriptUtil.toString(bytes));
        }
        return result;
    }

    @Override
    public String getScriptContent(String scriptName) throws IOException {
        return getResourceContent(scriptName);
    }

    /**
     * 加载配置文件.
     *
     * @param resourceName 资料.
     */
    public Properties importProperties(String resourceName) throws IOException {
        InputStream resourceAsStream = getResourceAsStream(resourceName);
        Properties properties = new Properties();
        properties.load(resourceAsStream);
        return properties;
    }

    /**
     * 获取内容.
     *
     * @param resourceName 资料文件.
     */
    public String getResourceContent(String resourceName) throws IOException {
        byte[] bytes = ScriptUtil.readToByteBuffer(resourceName);
        return ScriptUtil.toString(bytes);
    }

    /**
     * 资源文件.
     *
     * @param resourceName 文件.
     */
    public InputStream getResourceAsStream(String resourceName) throws IOException {
        byte[] bytes = ScriptUtil.readToByteBuffer(resourceName);
        return new ByteArrayInputStream(bytes);
    }
}
